const { app, BrowserWindow, ipcMain, dialog, Menu } = require('electron')
const path = require('path')
const { execSync } = require('child_process')
const fs = require('fs')
const DlvManager = require('./dlv-manager')

// 获取用户数据目录
const userDataPath = app.getPath('userData')
const historyFilePath = path.join(userDataPath, 'debug-history.json')

let mainWindow = null
let dlvManager = null
let dlvPath = 'dlv' // 默认使用系统PATH中的dlv

// 创建主窗口
function createWindow() {
  // 根据平台选择合适的图标格式
  let iconPath
  if (process.platform === 'win32') {
    iconPath = path.join(__dirname, '../build/icon.ico')
  }

  // 如果构建的图标不存在，回退到 public 目录的 SVG
  if (!fs.existsSync(iconPath)) {
    console.log('[Main] 构建的图标不存在，使用 SVG 图标:', iconPath)
    iconPath = path.join(__dirname, '../public/icon.svg')
  }

  mainWindow = new BrowserWindow({
    width: 1400,
    height: 900,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
      enableRemoteModule: true
    },
    title: 'GuLu - Go调试工具',
    backgroundColor: '#2e2e2e',
    autoHideMenuBar: true,
    icon: iconPath
  })

  // 移除菜单栏
  Menu.setApplicationMenu(null)

  // 加载应用
  // 判断是否为开发模式：检查是否已打包或环境变量
  const isDev = !app.isPackaged || process.env.NODE_ENV === 'development'

  if (isDev) {
    mainWindow.loadURL('http://localhost:5173')
    mainWindow.webContents.openDevTools()
  } else {
    mainWindow.loadFile(path.join(__dirname, '../dist/index.html'))
  }

  mainWindow.on('closed', () => {
    mainWindow = null
    if (dlvManager) {
      dlvManager.stopDebugger()
    }
  })
}

// 初始化调试管理器
async function initializeDlvManager() {
  dlvManager = new DlvManager()

  // 设置 dlv 路径
  dlvManager.setDlvPath(dlvPath)

  // 从设置中加载轮询间隔
  try {
    const settingsPath = path.join(userDataPath, 'debugger-settings.json')
    if (fs.existsSync(settingsPath)) {
      const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'))
      if (settings.pollingInterval) {
        dlvManager.setPollingInterval(settings.pollingInterval)
      }
    }
  } catch (error) {
    console.error('[Main] 加载轮询设置失败:', error)
  }

  // 监听dlv输出
  dlvManager.on('output', (data) => {
    if (mainWindow) {
      mainWindow.webContents.send('debugger:output', data)
    }
  })

  // 监听dlv错误
  dlvManager.on('error', (data) => {
    if (mainWindow) {
      mainWindow.webContents.send('debugger:error', data)
    }
  })

  // 监听dlv退出
  dlvManager.on('exit', (data) => {
    if (mainWindow) {
      mainWindow.webContents.send('debugger:exit', data)
    }
  })

  // 监听断点命中
  dlvManager.on('breakpoint-hit', (data) => {
    if (mainWindow) {
      mainWindow.webContents.send('debugger:breakpoint-hit', data)
    }
  })

  // 监听程序退出
  dlvManager.on('program-exited', (data) => {
    if (mainWindow) {
      mainWindow.webContents.send('debugger:program-exited', data)
    }
  })
}

// 检查dlv是否可用及版本
function checkDlvVersion(dlvExecutable) {
  try {
    const version = execSync(`"${dlvExecutable}" version`, {
      encoding: 'utf8',
      timeout: 5000
    })

    // 解析版本信息
    const match = version.match(/Delve Debugger\s+Version:\s+([\d.]+)/i)
    if (match) {
      return {
        available: true,
        version: match[1],
        path: dlvExecutable,
        fullOutput: version.trim()
      }
    }

    return {
      available: true,
      version: 'unknown',
      path: dlvExecutable,
      fullOutput: version.trim()
    }
  } catch (error) {
    return {
      available: false,
      error: error.message,
      path: dlvExecutable
    }
  }
}

// IPC处理程序
function setupIpcHandlers() {
  // 检查dlv状态
  ipcMain.handle('dlv:checkVersion', async () => {
    return checkDlvVersion(dlvPath)
  })

  // 选择dlv可执行文件
  ipcMain.handle('dlv:selectPath', async () => {
    const result = await dialog.showOpenDialog(mainWindow, {
      properties: ['openFile'],
      filters: [
        { name: 'Delve可执行文件', extensions: process.platform === 'win32' ? ['exe'] : [''] },
        { name: '所有文件', extensions: ['*'] }
      ],
      title: '选择Delve (dlv) 可执行文件'
    })

    if (result.canceled) {
      return { canceled: true }
    }

    const selectedPath = result.filePaths[0]

    // 验证选择的文件是否为有效的dlv
    const versionInfo = checkDlvVersion(selectedPath)

    if (versionInfo.available) {
      dlvPath = selectedPath
      // 更新DlvManager使用的dlv路径
      if (dlvManager) {
        dlvManager.setDlvPath(dlvPath)
      }
      return {
        canceled: false,
        path: selectedPath,
        version: versionInfo.version,
        success: true
      }
    } else {
      return {
        canceled: false,
        path: selectedPath,
        success: false,
        error: '所选文件不是有效的dlv可执行文件'
      }
    }
  })

  // 获取当前dlv路径
  ipcMain.handle('dlv:getPath', () => {
    return { path: dlvPath }
  })

  // 选择Go程序文件
  ipcMain.handle('dialog:selectFile', async () => {
    const result = await dialog.showOpenDialog(mainWindow, {
      properties: ['openFile'],
      filters: [
        { name: 'Go执行文件', extensions: ['exe', ''] },
        { name: '所有文件', extensions: ['*'] }
      ]
    })

    if (result.canceled) {
      return { canceled: true }
    }

    return { canceled: false, filePath: result.filePaths[0] }
  })

  // 启动调试器
  ipcMain.handle('debugger:start', async (event, { programPath, args }) => {
    try {
      const result = await dlvManager.startDebugger(programPath, args)
      return result
    } catch (error) {
      return { success: false, message: error.message }
    }
  })

  // 停止调试器
  ipcMain.handle('debugger:stop', async () => {
    return await dlvManager.stopDebugger()
  })

  // 继续执行
  ipcMain.handle('debugger:continue', async () => {
    return await dlvManager.continue()
  })

  // 暂停执行
  ipcMain.handle('debugger:pause', async () => {
    return await dlvManager.pause()
  })

  // 单步执行（步过）
  ipcMain.handle('debugger:stepOver', async () => {
    return await dlvManager.stepOver()
  })

  // 单步执行（步入）
  ipcMain.handle('debugger:stepInto', async () => {
    return await dlvManager.stepInto()
  })

  // 单步执行（步出）
  ipcMain.handle('debugger:stepOut', async () => {
    return await dlvManager.stepOut()
  })

  // 设置断点
  ipcMain.handle('debugger:setBreakpoint', async (event, { file, line, condition, hitCondition }) => {
    return await dlvManager.setBreakpoint(file, line, condition, hitCondition)
  })

  // 删除断点
  ipcMain.handle('debugger:clearBreakpoint', async (event, { id }) => {
    return await dlvManager.clearBreakpoint(id)
  })

  // 获取断点列表
  ipcMain.handle('debugger:getBreakpoints', () => {
    return dlvManager.getBreakpoints()
  })

  // 获取调用堆栈
  ipcMain.handle('debugger:getStacktrace', async (event, { depth, goroutineID }) => {
    return await dlvManager.getStacktrace(depth, goroutineID)
  })

  // 获取局部变量
  ipcMain.handle('debugger:getLocalVariables', async (event, { goroutineID, frameIndex, maxDepth }) => {
    return await dlvManager.getLocalVariables(goroutineID, frameIndex, maxDepth)
  })

  // 求值表达式
  ipcMain.handle('debugger:evaluate', async (event, { expression, maxDepth = 3 }) => {
    return await dlvManager.evaluate(expression, maxDepth)
  })

  // 获取当前状态
  ipcMain.handle('debugger:getState', async () => {
    const state = await dlvManager.getState()
    if (state) {
      return { success: true, state }
    } else {
      return { success: false, message: '无法获取状态' }
    }
  })

  // 获取调试器状态
  ipcMain.handle('debugger:getCurrentState', () => {
    return dlvManager.getCurrentState()
  })

  // 获取源文件列表
  ipcMain.handle('debugger:listSources', async (event, { filter }) => {
    return await dlvManager.listSources(filter)
  })

  // 获取 Goroutine 列表
  ipcMain.handle('debugger:listGoroutines', async () => {
    return await dlvManager.listGoroutines()
  })

  // 加载变量的子成员（按需加载）
  ipcMain.handle('debugger:loadVariableChildren', async (event, { expr, goroutineID, frameIndex }) => {
    return await dlvManager.loadVariableChildren(expr, goroutineID, frameIndex)
  })

  // 设置变量值
  ipcMain.handle('debugger:setVariable', async (event, { symbol, value, goroutineID, frameIndex }) => {
    return await dlvManager.setVariable(symbol, value, goroutineID, frameIndex)
  })

  // 读取调试历史记录
  ipcMain.handle('history:load', async () => {
    try {
      if (fs.existsSync(historyFilePath)) {
        const data = fs.readFileSync(historyFilePath, 'utf8')
        return { success: true, data: JSON.parse(data) }
      }
      return { success: true, data: [] }
    } catch (error) {
      console.error('读取历史记录失败:', error)
      return { success: false, message: error.message, data: [] }
    }
  })

  // 保存调试历史记录
  ipcMain.handle('history:save', async (event, { data }) => {
    try {
      // 确保目录存在
      const dir = path.dirname(historyFilePath)
      if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, { recursive: true })
      }

      fs.writeFileSync(historyFilePath, JSON.stringify(data, null, 2), 'utf8')
      return { success: true }
    } catch (error) {
      console.error('保存历史记录失败:', error)
      return { success: false, message: error.message }
    }
  })

  // 获取当前调试模式

  // 保存设置 (通用)
  ipcMain.handle('settings:save', async (event, { settings }) => {
    try {
      const settingsPath = path.join(userDataPath, 'debugger-settings.json')
      fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8')

      // 如果轮询间隔发生变化，动态更新 dlvManager
      if (settings.pollingInterval && dlvManager) {
        dlvManager.setPollingInterval(settings.pollingInterval)
      }

      return { success: true }
    } catch (error) {
      console.error('[Main] 保存设置失败:', error)
      return { success: false, message: error.message }
    }
  })

  // 加载设置 (通用)
  ipcMain.handle('settings:load', async () => {
    try {
      const settingsPath = path.join(userDataPath, 'debugger-settings.json')
      if (fs.existsSync(settingsPath)) {
        const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'))
        return { success: true, settings }
      }
      return { success: true, settings: {} }
    } catch (error) {
      console.error('加载设置失败:', error)
      return { success: false, message: error.message, settings: {} }
    }
  })
}

// 应用准备就绪之前先设置IPC处理器
setupIpcHandlers()

// 应用准备就绪
app.whenReady().then(() => {
  initializeDlvManager()
  createWindow()

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow()
    }
  })
})

// 所有窗口关闭
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

// 应用退出前清理
app.on('before-quit', () => {
  if (dlvManager) {
    dlvManager.stopDebugger()
  }
})
